#pragma once
#include <mutex>
#include <iostream>

namespace LockModule
{
    class Mutex
    {
    private:
        Mutex(const Mutex &) = delete;
        Mutex &operator=(const Mutex &) = delete;

    public:
        Mutex()
        {
            int n = pthread_mutex_init(&_lock, nullptr);
            (void)n;
        }
        void Lock()
        {
            int n = pthread_mutex_lock(&_lock);
            (void)n;
        }
        void unlock()
        {
            int n = pthread_mutex_unlock(&_lock);
            (void)n;
        }
        ~Mutex()
        {
            int n = pthread_mutex_destroy(&_lock);
            (void)n;
        }
        pthread_mutex_t *LockPtr()
        {
            return &_lock;
        }
    private:
        pthread_mutex_t _lock;
    };
    class LockGuard
    {
    public:
        LockGuard(Mutex &mtx) : _mtx(mtx)
        { 
            _mtx.Lock(); 
        }
        ~LockGuard() { _mtx.unlock(); }
        
    private:
        Mutex &_mtx;
    };
}